<template>
  <!-- 表单组件核心代码 -->
  <el-form class="freeForm" ref="formRef" :model="model" v-bind="$attrs" v-on="$listeners" :rules="props.isAllRules?rules:props.rules"
    @validate="$handleFormValidate" label-position="right">
    <el-row :gutter="15">
      <!-- 显示hidden为false的表单项 -->
      <el-col v-for="(item, index) in props.formItemConfig" :key="index" :span="item.span" v-show="!item.hidden">
        <div class="freeFormItem">
          <!-- 处理标题 -->
          <p v-if="item.title" class="cgtitle">{{ item.title }}</p>
          <el-form-item v-else :label="item.label" :prop="item.prop" :label-width="item.labelWidth?item.labelWidth:'80px'" label-position="right">
            <!-- 动态渲染组件 -->
            <template v-if="item.component=='select'">
              <el-select clearable v-model="model[item.prop]" @change="changeValue(item, $event,item.onChange)" v-bind="$attrs" style="width:100%"
                :disabled="item.isEnd==true?false:(disabled?disabled:item.disabled)" :multiple="item.multiple">
                <el-option v-for="(option,i) in item.options" :key="i" :label="item.optionsText?option[item.optionsText.label]:option.label"
                  :value="item.optionsText?option[item.optionsText.value]:option.value"></el-option>
              </el-select>
            </template>
            <template v-if="item.component=='radio'">
              <el-radio-group v-model="model[item.prop]" class="ml-4" @change="changeValue(item, $event,item.onChange)" style="width:100%"
                :disabled="item.isEnd==true?false:(disabled?disabled:item.disabled)">
                <el-radio :label="option.value" size="large" v-for="(option,i) in item.options" :key="i">{{option.label}}</el-radio>
              </el-radio-group>
            </template>

            <template v-if="item.component=='input'||item.component=='textarea'||item.component=='password'">
              <el-input v-model="model[item.prop]" @input="changeValue(item, $event,item.onChange)" placeholder="请输入"
                :type="item.component=='textarea'||item.type=='textarea'?'textarea':item.component=='password'?'password':''"
                :show-password="item.component=='password'" :disabled="item.isEnd==true?false:(disabled?disabled:item.disabled)" :rows="5">
                <template #append   v-if="item.append">
                  <div>{{item.append}}</div>
                </template>
              </el-input>
            </template>
            <template v-if="item.component=='number'">
              <div style="display: flex;align-items: center;width:100% ;">
                <el-input-number v-model="model[item.prop]" :controls="false" @input="changeValue(item, $event,item.onChange)" placeholder="请输入"
                  :style="{'width':!item.suffix?'100%':'87%'}" :disabled="item.isEnd==true?false:(disabled?disabled:item.disabled)" />
                <div style="width:12% ;margin-left: 5px;" v-if="item.suffix"> {{item.suffix}}</div>

              </div>

            </template>

            <template v-if="item.component=='date'">
              <el-date-picker v-model="model[item.prop]" @change="changeValue(item, $event,item.onChange)" :type="item.type?item.type:'datetime'"
                :value-format="item.format?item.format:'YYYY-MM-DD HH:mm:ss'" placeholder="请选择" style="width:100%"
                :disabled="item.isEnd==true?false:(disabled?disabled:item.disabled)"></el-date-picker>
            </template>

            <template v-if="item.component=='tree'" :ref="item.ref">
              <el-tree-select v-model="model[item.prop]" style="width:100%" :data="item.options" @node-click="handleNodeClick(item, $event,item.onChange)"
                :render-after-expand="false" :value-key="item.valuekey?item.valuekey:'id'" :props="item.props" :disabled="disabled?disabled:item.disabled"
                check-strictly clearable />
            </template>

            <template v-if="item.component=='cascader'" :ref="item.ref">
              <el-cascader style="width:100%" v-model="model[item.prop]" :options="item.options" :props="item.props"
                @change="changeValue(item, $event,item.onChange)" placeholder="请选择" :disabled="item.isEnd==true?false:(disabled?disabled:item.disabled)" />
            </template>

            <template v-if="item.component=='carcolor'" :ref="item.ref">
              <el-input v-model="model[item.prop]" @input="changeValue(item, $event,item.onChange)" placeholder="请输入"
                :type="item.component=='textarea'||item.type=='textarea'?'textarea':item.component=='password'?'password':''" style="width:62%"
                :show-password="item.component=='password'" :disabled="item.isEnd==true?false:(disabled?disabled:item.disabled)" />&nbsp;&nbsp; -&nbsp;&nbsp;
              <el-select v-model="model.carColor" @change="changeValue({prop:'carColor'}, $event,item.onChange)" style="width:30%"
                :disabled="item.isEnd==true?false:(disabled?disabled:item.disabled)">
                <el-option v-for="(option,i) in car_color" :key="i" :label="option.label" :value="option.value"></el-option>
              </el-select>
            </template>

            <template v-if="item.component=='file'">
              <FileUpload :modelValue="model[item.prop]" v-model="model[item.prop]" :disabled="item.isEnd==true?false:(disabled?disabled:item.disabled)" />
            </template>
            <template v-if="item.component=='img'">
              <ImageUpload :modelValue="model[item.prop]" v-model="model[item.prop]" :disabled="item.isEnd==true?false:(disabled?disabled:item.disabled)" />
            </template>
            <template v-if="item.component=='imgPreview'">
              <image-preview :src="model[item.prop]" :width="70" :height="70" />
            </template>

          </el-form-item>
        </div>
      </el-col>
    </el-row>

  </el-form>
</template>
  
<script setup>
import ImageUpload from "@/components/ImageUpload"
import FileUpload from "@/components/FileUpload"
import { defineEmits, defineProps, defineExpose } from "vue";
const { proxy } = getCurrentInstance();
const { car_color } = proxy.useDict('car_color');
const emit = defineEmits(["parent-event", "getformModel"]);
const formRef = ref({})
const model = ref({})
const rules = ref()
/**
 * @desc 表单组件
 * @param {Object} formRef - el-form 的 ref 名称
 * @param {Object} model - 表单数据模型
 * @param {Object} formItemConfig - el-form-item 配置项
 * @param {Object} rules - el-form-item 验证规则
 */
const props = defineProps({

  // 表单数据模型
  model: {
    type: Object
  },
  // 表单项配置
  formItemConfig: {
    type: Array,
    default: [],
  },
  // 表单验证规则
  rules: {
    type: Object,
    default: {},
  },
  modelCode: {
    type: String,
    default: "",
  },
  isAllRules: { type: Boolean, default: false, },
  disabled: { type: Boolean, default: false, }
});


watch(() => props.model, (New, Old) => {
  model.value = New;
}, { deep: true })

if (props.isAllRules) {
  rules.value = {}
  props.formItemConfig.forEach(item => {
    if (item.rules) {
      rules.value[item.prop] = item.rules
    } else if (item.label != '备注' && !item.isRule) {
      rules.value[item.prop] = [
        { required: true, message: item.label + "不能为空", trigger: "blur" }]
    }

  })
}
onMounted(() => {
  model.value = props.model;
})
const placeholder = () => {
  return (item) => {
    if (item.placeholder) return item.placeholder;
    const arr = ["el-input", "el-input-number"];
    return !item.component || arr.includes(item.component)
      ? `请输入${item.label || ""}`
      : `请选择${item.label || ""}`;
  };
}

/**
     * 验证表单并执行回调函数
     * @param {Function} cb - 表单验证通过后的回调函数
     * @returns {boolean} - 表单验证结果
     */

const accountLoginAction = () => {
  formRef.value?.validate((valid) => {
    if (valid) {
      // 如果表单验证通过，执行提交操作
      emit("getformModel", valid);
    } else {
      return false;
    }
  });
};

/**
 * 更新表单数据模型到父组件
 */
const changeValue = (item, e, eventChange) => {
  emit("parent-event", { val: e, name: item.prop });
  if (eventChange) {
    eventChange(e)
  }

}

const handleNodeClick = (item, e, eventChange) => {
  emit("parent-event", { val: e[item.valuekey ? item.valuekey : 'id'], name: item.prop, id: e.id });
  if (eventChange) {
    eventChange(e)
  }
}
defineExpose({
  accountLoginAction
})
</script>

<style scoped>
.freeFormItem .el-form-item.el-form-item--default.asterisk-left {
  display: flex;
}
.el-form--default.el-form--label-top .el-form-item .el-form-item__labe {
  width: 100px;
  flex-shrink: 0;
}
</style>
  